package top.malaoshi.webmvc.parameter;

import top.malaoshi.webmvc.info.MethodsArgumentInfo;
import org.springframework.web.bind.annotation.RequestParam;
import top.malaoshi.webmvc.exception.AnnotationConfigException;
import top.malaoshi.webmvc.exception.MissingRequestParameterException;
import top.malaoshi.webmvc.exception.ParameterTypeMatchValueException;

public abstract class AbstractResolver implements RequestParamAndMethodArgsResolver {

    /**
     * 取出名字，该名字用于 从request对象中取值
     * 默认是形参名，当有 RequestParam 注解时，按照注解配置名字
     * @param mai
     * @return
     */
    public String getName(MethodsArgumentInfo mai){
        // 默认按照形参名，从request对象中取值
        String ret = mai.getName();
        // 当有 RequestParam 注解时，按照注解配置名字，从request对象中取值
        RequestParam requestParam = mai.getRequestParam();
        if(requestParam!=null) {
            String name = requestParam.name();
            String value = requestParam.value();

            if(!"".equals(name)){
                ret = name;
            }else if(!"".equals(value)){
                ret = value;
            }
        }
        return ret;
    }
    /**
     * 检查@RequestParam 注解的 name值和value值
     * 如果name和value的值都不是 ""，那么必须相同
     * @param mai
     */
    public void checkNameAndValue(MethodsArgumentInfo mai){
        RequestParam requestParam = mai.getRequestParam();
        if(requestParam!=null) {
            String value = requestParam.value();
            String name = requestParam.name();
            if (!"".equals(value) && !"".equals(name) && !value.equals(name)) {
                String msg = String.format("@RequestParam注解的name与value应该一致");
                throw new AnnotationConfigException(msg);
            }
        }
    }

    /**
     * 校验 @RequestParam 注解的 Required，如果required为true，那么返回值必须不能为null
     * @param ret 返回值
     * @param mai
     */
    public void checkRequired(Object ret , MethodsArgumentInfo mai){
        RequestParam requestParam = mai.getRequestParam();
        if(requestParam!=null && ret == null) {
            String name = requestParam.name();
            String value = requestParam.value();

            String parameterName = mai.getName();
            if(!"".equals(name)){
                parameterName = name;
            }else if(!"".equals(value)){
                parameterName = value;
            }

            boolean required = requestParam.required();
            if (required ) {
                String msg = String.format("请求中必须提供[ %s ]参数", parameterName);
                throw new MissingRequestParameterException(msg);
            }
        }
    }

    /**
     *  如：Controlle方法形参是 int 类型，从request取出值是null
     *  int类型变量不能赋值null，此时用该类封装异常
     * @param mai
     * @param parameterValue
     */
    public void checkNull(MethodsArgumentInfo mai,
                          Object parameterValue,
                          Class type){

        if( mai.getType() == type){
            String msg = String.format("从request取出的值是[ %s ]，但形参[ %s ]类型是[ %s ]，不能赋值",
                    parameterValue,mai.getName(),mai.getType().getName());
            throw new ParameterTypeMatchValueException(msg);
        }
    }
}
